using Circus.CodeEditor;
using Circus.Syntax.CodeCompletion;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Circus.CodeEditor.CodeCompletion
{
	[DesignerCategory("Code"), DesignTimeVisible(false), ToolboxItem(false)]
	public class CompletionHint : Control
	{
		private ICodeCompletionProvider provider;
		private Painter painter;
		private HintSyntaxPaint syntaxPaint;
		private Size hintSize;
		private EventHandler updateSize;
		private Point startPos;
		private int selectedIndex = 1;
		public bool NeedArrows
		{
			get
			{
				return this.syntaxPaint.NeedArrows;
			}
		}
		public SyntaxPaint SyntaxPaint
		{
			get
			{
				return this.syntaxPaint;
			}
		}
		public ICodeCompletionProvider Provider
		{
			get
			{
				return this.provider;
			}
			set
			{
				if (this.provider != value)
				{
					this.provider = value;
					this.ProviderChanged();
				}
			}
		}
		public Point StartPos
		{
			get
			{
				return this.startPos;
			}
			set
			{
				this.startPos = value;
				this.syntaxPaint.StartPos = value;
			}
		}
		public int SelectedIndex
		{
			get
			{
				return this.selectedIndex;
			}
			set
			{
				if (this.selectedIndex != value)
				{
					this.selectedIndex = value;
					this.OnSelectedIndexChanged();
				}
			}
		}
		public Size HintSize
		{
			get
			{
				return this.hintSize;
			}
		}
		public EventHandler UpdateSize
		{
			get
			{
				return this.updateSize;
			}
			set
			{
				this.updateSize = value;
			}
		}
		protected void UpdateControlSize()
		{
			this.hintSize = this.syntaxPaint.UpdateSize();
			if (this.UpdateSize != null)
			{
				this.UpdateSize(this, EventArgs.Empty);
			}
			base.Invalidate();
		}
		protected override bool IsInputKey(Keys keyData)
		{
			Keys value = keyData & Keys.KeyCode;
			return Array.IndexOf<Keys>(EditConsts.NavKeys, value) >= 0 || base.IsInputKey(keyData);
		}
		protected override void OnFontChanged(EventArgs e)
		{
			base.OnFontChanged(e);
			this.painter.Clear();
		    this.painter.font = this.Font;
		    this.UpdateControlSize();
		}
		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown(e);
			if (e.Button == MouseButtons.Left && this.NeedArrows)
			{
				this.ChangeSelection(!this.syntaxPaint.LeftArrowArea.Contains(e.X, e.Y));
			}
		}
		protected override void OnPaint(PaintEventArgs e)
		{
			this.painter.BeginPaint(e.Graphics);
			try
			{
				this.syntaxPaint.PaintSyntax(this.painter, 0, this.syntaxPaint.Strings.Count - 1, new Point(0, 0), base.ClientRectangle, new Point(0, 0), false);
			}
			finally
			{
				this.painter.EndPaint();
			}
		}
		protected void StringChanged()
		{
			this.syntaxPaint.ProviderChanged(this.provider, this.selectedIndex);
			this.UpdateHint();
			this.UpdateControlSize();
		}
		protected virtual void ProviderChanged()
		{
			this.selectedIndex = 0;
			this.StringChanged();
		}
		protected virtual HintSyntaxPaint CreateSyntaxPaint(Painter painter)
		{
			return new HintSyntaxPaint(painter, this);
		}
		public bool UpdateHint()
		{
			bool result;
			if (this.provider != null && this.selectedIndex < this.provider.Count && this.syntaxPaint.UpdateHint())
			{
				this.UpdateControlSize();
				result = true;
			}
			else
			{
				result = false;
			}
			return result;
		}
		protected virtual void OnSelectedIndexChanged()
		{
			this.StringChanged();
		}
		public CompletionHint()
		{
			this.painter = new Painter();
		    this.painter.font = this.Font;
		    this.syntaxPaint = this.CreateSyntaxPaint(this.painter);
			this.hintSize = base.Size;
			base.SetStyle(ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.StandardClick | ControlStyles.StandardDoubleClick | ControlStyles.AllPaintingInWmPaint, true);
		}
		public void ResetContent()
		{
			this.ProviderChanged();
		}
		public void ChangeSelection(bool inc)
		{
			if (this.provider != null)
			{
				int num = this.selectedIndex;
				if (inc)
				{
					num++;
					if (num >= this.provider.Count)
					{
						num = 0;
					}
				}
				else
				{
					num--;
					if (num < 0)
					{
						num = Math.Max(this.provider.Count - 1, 0);
					}
				}
				this.SelectedIndex = num;
			}
		}
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (this.syntaxPaint != null)
				{
					this.syntaxPaint.Dispose();
					this.syntaxPaint = null;
				}
			}
			base.Dispose(disposing);
		}
	}
}
